/**
 * Test Spec (using Jasmine Java Script Unit Test Framework)
 * http://pivotal.github.com/jasmine/
 * 
 * Contains unit tests that require access to a Paging Service
 */

beforeEach(function () {
	baseException = new VPAGER.Exception("","Any VPAGER Exception");
	validationEx = new VPAGER.Exception().ValidationError("");
	illegalParamsEx = new VPAGER.Exception().IllegalParameters("");
	srvRequestEx = new VPAGER.Exception().ServiceRequestError(
			"Service Request Error", "", "");
	
	// Customer Match for VPAGER.Exception objects
	this.addMatchers({
		toThrowVPagerEx:	function(expected) {
			  var result = false;
			  var exception = undefined;
			  if (typeof this.actual != 'function') {
			    throw new Error('Actual is not a function');
			  }
			  try {
			    this.actual();
			  } catch (e) {
			    exception = e;
			  }
			  if (exception) {
			    result = (exception instanceof VPAGER.Exception &&
			    		  expected instanceof VPAGER.Exception &&
			    		  (expected.name === "" || exception.name === expected.name));
			  }
			
			  var not = this.isNot ? "not " : "";
			
			  this.message = function() {
			    if (exception) {
			      return ["Expected function " + not + "to throw", expected ? expected.message || expected : "an exception", ", but it threw", exception.message || exception].join(' ');
			    } else {
			      return "Expected function to throw an exception.";
			    }
			  };
			
			  return result;
		}
	});
});

describe("Logging", function() {

	describe("Log4Javascript Setup", function() {
		it("Should accept log4javascript", function() {
            if (!VPAGER.Logging().getLogger() ||
                VPAGER.Logging().getLogger().ID !== "L4JS")
            {
                // Create an L4JS logger object to redirect log message to TRACE.
                var logger = VPC.createProductionLogger();
            
                // Install Log4Javascript so trace logging is now in place for 
                // remainder of unit tests.
                new VPAGER.Logging().setLogger(logger);
                expect(VPAGER.Logging().getLogger()).toEqual(logger);
            }
		});
	});
});


describe("ServerProxy API Tests", function() {
    var sp1 = null;
    var sp2 = null;
    var pcode1 = 'T01';
    var pcode2 = 'T02';
    var page1 = null;
    var pageCount = null;
    var request1 = null;
    var request2 = null;

    beforeEach(function() {
        sp1 = new VPAGER.ServerProxy();
        request1 = new VPAGER.ParentPage({ Code: pcode1 });
        request2 = new VPAGER.ParentPage({ Code: pcode2 });
    });

     describe("Status Monitor Tests", function() {
        beforeEach(function() {
            // Create to Listeners for testing
            listener1 = new VPC.SimpleListener();
            listener2 = new VPC.SimpleListener();
       });

        it("Can Enable StatusMonitor", function() {
            var statusmon = sp1.getStatusMonitor();
            expect(statusmon.isEnabled()).toBeFalsy();
            expect(statusmon.isRunning()).toBeFalsy();
            
            statusmon.enable();
            expect(statusmon.isEnabled()).toBeTruthy();
            expect(statusmon.isRunning()).toBeFalsy();
            
            statusmon.registerChangeListener(listener1);
            expect(statusmon.isRunning()).toBeTruthy();
           
            statusmon.disable();
            expect(statusmon.isRunning()).toBeFalsy();

            statusmon.enable();
            expect(statusmon.isRunning()).toBeTruthy();

            statusmon.deregisterChangeListener(listener1);
            expect(statusmon.isRunning()).toBeFalsy();
        });

        it("Can Receive Display Events", function() {
            var statusmon = sp1.getStatusMonitor();
            statusmon.setRefreshRate(1);
            expect(statusmon.getRefreshRate()).toEqual(1);
            
            //Make sure Display is off (force)
            sp1.getDisplayHandler().disableDisplay(true);
            // Force local statusmon object to synch with server
            statusmon.refresh();
 
            statusmon.registerChangeListener(listener1);
            statusmon.enable();
            expect(statusmon.isRunning()).toBeTruthy();
            
            waits(1500);
            runs(function() {
                // No changes so far
                expect(listener1._called).toEqual(0);
                // Turn Display On
                sp1.getDisplayHandler().enableDisplay();
            });
            
            waits(1500);
            runs(function() {
                // Display Status Changed
                expect(listener1._called).toEqual(1);
                var status = listener1._event;
                expect(status.getDisplayState()).toEqual("ENABLED");
                // Verify the status returned via event matches the
                // one returned by the StatusMonitor directly.
                expect(statusmon.getStatus().sameAs(status)).toBeTruthy();
                 // Turn Display On (no effect)
                sp1.getDisplayHandler().enableDisplay();
           });

            waits(1500);
            runs(function() {
                // Display Status Should Not Be Changed
                expect(listener1._called).toEqual(1);
                var status = listener1._event;
                expect(status.getDisplayState()).toEqual("ENABLED");
                //Make sure Display is off (force)
                sp1.getDisplayHandler().disableDisplay(true);
           });

            waits(1500);
            runs(function() {
                // Display Status Should Be Changed
                expect(listener1._called).toEqual(2);
                var status = listener1._event;
                expect(status.getDisplayState()).toEqual("DISABLED");
           });

          });
          
        it("Can Disable StatusMonitor", function() {
            var statusmon = sp1.getStatusMonitor();
            // Call after test to disable polling loop.
            statusmon.disable();
        });
    });

   describe("Page Monitor Tests", function() {
        beforeEach(function() {
            // Create to Listeners for testing
            listener1 = new VPC.SimpleListener();
            listener2 = new VPC.SimpleListener();
       });

        it("Can Enable PageMonitor", function() {
            var pagemon = sp1.getPageMonitor();
            expect(pagemon.isEnabled()).toBeFalsy();
            expect(pagemon.isRunning()).toBeFalsy();
            
            pagemon.enable();
            expect(pagemon.isEnabled()).toBeTruthy();
            expect(pagemon.isRunning()).toBeFalsy();
            
            pagemon.registerChangeListener(listener1);
            expect(pagemon.isRunning()).toBeTruthy();
           
            pagemon.disable();
            expect(pagemon.isRunning()).toBeFalsy();

            pagemon.enable();
            expect(pagemon.isRunning()).toBeTruthy();

            pagemon.deregisterChangeListener(listener1);
            expect(pagemon.isRunning()).toBeFalsy();
        });

        it("Can receive Add Page events", function() {
            var pagemon = sp1.getPageMonitor();
            pagemon.setRefreshRate(1);
            expect(pagemon.getRefreshRate()).toEqual(1);
            
            //Clear current pages
            sp1.cancelAllPages();
            // Force local pagemon object to synch with server
            pagemon.refresh();

            pagemon.registerChangeListener(listener1);
            pagemon.enable();
            expect(pagemon.isRunning()).toBeTruthy();
            
            waits(1500);
            runs(function() {
                // 0 Add = 0 Events
                expect(listener1._called).toEqual(0);
                page1 = sp1.submitNewPage(request1);
            });
            
            waits(1500);
            runs(function() {
                // 1 Add = 1 Events
                expect(listener1._called).toEqual(1);
                var pages = listener1._event;
                expect(pages.length).toEqual(1);
                expect(pages[0].exactSameAs(page1)).toBeTruthy();
                // Resubmit same page - catch/ignore exception
                try {
                    sp1.submitNewPage(request1);
                } catch (e){}
            });

            waits(1500);
            runs(function() {
                // Last add should have failed (duplicate)
                // 1 Add = 1 Events
                expect(listener1._called).toEqual(1);
            });

          });
          
        it("Can receive Modified Page events", function() {
            var pagemon = sp1.getPageMonitor();
            var page1 = undefined;
            pagemon.disable();
            pagemon.setRefreshRate(1);
            expect(pagemon.getRefreshRate()).toEqual(1);
            
            //Clear current pages at server
            sp1.cancelAllPages();
            // Force local pagemon object to synch with server
            pagemon.refresh();
            
            pagemon.registerChangeListener(listener1);
            pagemon.enable();
            expect(pagemon.isRunning()).toBeTruthy();
            
            waits(1500);
            runs(function() {
                // Add a page
                expect(listener1._called).toEqual(0);
                page1 = sp1.submitNewPage(request1);
            });
            
            waits(1500);
            runs(function() {
                expect(listener1._called).toEqual(1);
                // Modify page 
                page1.setLocation("Testville");
                sp1.modifyPage(page1);
            });

            waits(1500);
            runs(function() {
                // 1 Add + 1 Modify = 2 Events
                expect(listener1._called).toEqual(2);
                // Re-Modify page (No Actual Changes) 
                sp1.modifyPage(page1);
            });

            waits(1500);
            runs(function() {
                // Last Modify call did not change anything so
                // we do not expect another event to listener
                expect(listener1._called).toEqual(2);
            });

          });
         
        it("Can Disable PageMonitor", function() {
            var pagemon = sp1.getPageMonitor();
            // Call after test to disable polling loop.
            pagemon.disable();
         });
    });

});



